package com.fili.resources.texture;


import org.lwjgl.opengl.GL11;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;


/**
 * Created by Claudiu-Florin FILIMON
 * Date: Nov 3, 2006
 * Time: 5:12:27 PM
 * Revision: 0
 */
public class Texture
{
    private int textureID;
    private int width;
    private int height;


    //only TextureFactory has access
    Texture(BufferedImage bImg)
    {
        this(bImg, true, false, false);
    }

    Texture(BufferedImage bImg, boolean transparent)
    {
        this(bImg, transparent, false, false);
    }

    Texture(BufferedImage bImg, boolean transparent, boolean stretch)
    {
        this(bImg, transparent, stretch, false);
    }

    Texture(BufferedImage bImg, boolean transparent, boolean stretch, boolean square)
    {
        width = 1;
        while (width < bImg.getWidth())
            width *= 2;
        height = 1;
        while (height < bImg.getHeight())
            height *= 2;
        if (square)
        {
            if (width < height)
                width = height;
            else
                height = width;
        }

        BufferedImage texImg;
        Color fillColor;
        int size;
        int texFormat;

        if (bImg.getColorModel().hasAlpha()&&transparent)
        {
            texImg = new BufferedImage(width, height,BufferedImage.TYPE_4BYTE_ABGR);
            fillColor = TextureFactory.getTransparentColor();
            size = 4*width*height;
            texFormat = GL11.GL_RGBA;
        }
        else
        {
            texImg = new BufferedImage(width, height,BufferedImage.TYPE_3BYTE_BGR);
            fillColor = TextureFactory.getOpaqueColor();
            size = 3*width*height;
            texFormat = GL11.GL_RGB;
        }

        Graphics g = texImg.getGraphics();
        g.setColor(fillColor);
        g.fillRect(0,0,width,height);
        g.drawImage(bImg, 0, 0, null);
        ByteBuffer scratch = ByteBuffer.allocateDirect(size);
        byte[] data = (byte[]) texImg.getRaster().getDataElements(0, 0, width, height, null);
        scratch.clear();
        scratch.put(data);
        scratch.rewind();
        IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        GL11.glGenTextures(buf);
        textureID = buf.get(0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, texFormat, width, height, 0, texFormat, GL11.GL_UNSIGNED_BYTE, scratch);
    }


    public void bind(int target)
    {
        GL11.glBindTexture(target, textureID);
    }
}
